package cl.regalloc.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

import cl.regalloc.graph.InterferenceGraph;
import cl.regalloc.graph.Node;

/** LabeledListSet represents a set of lists. */

@SuppressWarnings("all")
public class LabeledListSet {

	private int highestLabel = 0;

	private ArrayList listSet = null;
	private int numElements = 0;

	public LabeledListSet(InterferenceGraph graph) {
		this.numElements = graph.getGraph().size();
		this.listSet = new ArrayList(graph.getGraph().size());
		for(int i = 0; i < graph.getGraph().size(); i++)
			listSet.add(i, new HashSet());
		for (Node currentNode : graph.getGraph().values()) {
			currentNode.setMcsStatus(Node.MCS_VISITED);
			((HashSet)listSet.get(0)).add(currentNode);
		}
	}


	public void update(Node node) {
		updateCardTable(node.getSuccs());
		updateCardTable(node.getPrdcs());
	}

	private void updateCardTable(HashMap<String, Node> hashMap) {
		for (Node currentNode : hashMap.values()) {
			switch(currentNode.getMcsStatus()) {
			case Node.MCS_SPILT: break;
			case Node.MCS_VISITED: {
				int cardinality = currentNode.getCardinality();
				((HashSet)listSet.get(cardinality)).remove(currentNode);
				currentNode.incCardinality();
				if( (cardinality + 1) > highestLabel )
					highestLabel++;
				((HashSet)listSet.get(cardinality + 1)).add(currentNode);
				break;
			}
			default: break;
			}
		}
	}


	public Node getNextNode() {
		if(highestLabel < 0)
			return null;
		while(((HashSet)listSet.get(highestLabel)).isEmpty()) {
			highestLabel--;
			if(highestLabel < 0)
				return null;
		}
		Node node = null;
		Iterator i = ((HashSet)listSet.get(highestLabel)).iterator();
		if(i.hasNext()) {
			node = (Node)i.next();
			node.setMcsStatus(Node.MCS_SPILT);
			this.numElements--;
			i.remove();
		}
		return node;
	}

	public int size() {
		return this.numElements;
	}
}
